home *** CD-ROM | disk | FTP | other *** search
- ///--------------------------------------------------------------------------------------
- // Scrolling Demo.c
- //
- // By Vern Jensen. Created in August of 1995
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWFPSReport.h>
- #include <SWIncludes.h>
- #include <SWGameUtils.h>
- #include <BlitPixieScaled.h>
-
- #include "SWApplication.h"
- #include "Circular Demo.h"
-
-
- #define kFullScreenWindow true // 640x480 instead of 512x384
- #define kWorldRectInset 0 // Make the SpriteWorld smaller?
- #define kInterlacedMode false // NOT compatible with the zoom out intro!
- #define kSyncToVBL false // Sync SpriteWorld to VBL?
- #define kMaxFPS 30 // Set to 0 for unrestricted speed
-
- #define kDoZoomOutIntro true // turn this off if the scaling intro is too slow
-
- #define kScrollSpeed 10 // keyboard scrolling speed
- #define kNumSprites 100 // number of balls
- #define kMaxSpriteMoveDelta 4 // maximum vert & horiz speed of balls
-
-
- #define kSpriteMoveDelta 20 // Try 5, 10, 20, or 40
- #define kDiamondSpace 8 // How far apart the diamonds are spaced
- // (try 1!)
-
- #define kSpriteMoveDistance 80 // How far the sprite can move from
- // the center of the screen, in pixels.
- // Try making this value higher!
-
- // Number of ticks to wait before changing tile image; 0 = change every frame
- #define kDiamondFrameRate 8 // How often diamond tiles change frames
- #define kWallFrameRate 120 // How often wall changes frames
-
- #define kBWPictResIDOffset 100
- #define kTileWidth 40
- #define kTileHeight 40
- #define kTileMapRows 96 // This will create a virtual circular world
- #define kTileMapCols 144 // whose bounds are evenly divisible by 640x480
-
- #define kStartRow 5 // Starting position of sprite
- #define kStartCol 5 // in tile col and row
-
-
- #define kLeftArrowKey 0x7B
- #define kRightArrowKey 0x7C
- #define kDownArrowKey 0x7D
- #define kUpArrowKey 0x7E
-
- #define kLeftKeyPad 0x56
- #define kRightKeyPad 0x58
- #define kDownKeyPad 0x54
- #define kUpKeyPad 0x5B
-
- #define kEscKey 0x35
- #define kPlusKey 0x18
- #define kMinusKey 0x1B
- #define kReturnKey 0x24
-
-
- #define kNoKey 0
- #define kLeftKey 1
- #define kUpKey 2
- #define kRightKey 3
- #define kDownKey 4
-
-
- enum tileIDs
- {
- kWallTile,
- kLastWallTile,
- kGrassTile,
- kBlackTile,
- kDiamondTile,
- kDiamondTile2,
- kLastDiamondTile,
-
- kTunnelTile1,
- kTunnelTile2,
- kTunnelTile3,
- kTunnelTile4,
- kTunnelTile5,
- kTunnelTile6,
- kWireTile1,
- kWireTile2,
-
- kMaxNumTiles
- };
-
-
-
- /***********/
- /* Globals */
- /***********/
-
- SpriteWorldPtr gSpriteWorldP;
- SpriteLayerPtr gBallSpriteLayerP, gTopSpriteLayerP, gBottomSpriteLayerP, gMeterSpriteLayerP;
- TileMapStructPtr gTileMapStructP;
- TileMapPtr gTileMap;
- SpritePtr gSimpleSpriteP, gDiamondMeterSpriteP;
- SpritePtr gSpriteArray[kNumSprites];
- DrawProcPtr gSpriteDrawProc, gScreenDrawProc;
- DoubleDrawProcPtr gDoubleRectDrawProc;
- WindowPtr gWindowP;
- Rect gScreenMidRect;
- short gScaledWidth, gScaledHeight, gOriginalWidth, gOriginalHeight;
-
- long gNumDiamondsInMap = 0; // Number of diamonds in the TileMap
- long gNumDiamonds = 0; // Number of diamonds sprite has collected
-
- struct moveKeys // Keeps track of which keys are up and which are down
- {
- Boolean up;
- Boolean right;
- Boolean down;
- Boolean left;
- } gScrollKeys, gBallKeys;
-
- Boolean gPlusKeyIsDown = 0, gMinusKeyIsDown = 0, gReturnKeyIsDown = 0;
-
-
-
- ///--------------------------------------------------------------------------------------
- // Main
- ///--------------------------------------------------------------------------------------
-
- void main( void )
- {
- Initialize(kNumberOfMoreMastersCalls);
-
- if (SWHasSystem7())
- {
- AllowKeyUpEvents(); // Part of SWGameUtils.c
- SetCursor(*GetCursor(watchCursor));
-
- CreateSpriteWorld();
- SetUpTiling();
- CreateMainBallSprite();
- CreateBallSprites();
- CreateDiamondMeterSprite();
-
- SetCursor(&qd.arrow);
- HideCursor();
-
- SetUpAnimation();
- RunAnimation();
- ShutDown();
-
- RestoreEventMask(); // Call this after AllowKeyUpEvents
- }
- else
- {
- CantRunOnThisMachine();
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- void CreateSpriteWorld( void )
- {
- Rect offscreenRect, worldRect, windRect;
- RgnHandle mBarUpdateRgn;
- OSErr err;
-
- gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
-
- if (gWindowP != NULL)
- {
- if (kFullScreenWindow == true)
- {
- // Fill screen, but no larger than 640x480
- SizeWindow(gWindowP, SW_MIN(640, qd.screenBits.bounds.right),
- SW_MIN(480, qd.screenBits.bounds.bottom), false);
- MoveWindow(gWindowP, 0, 0, false);
- }
-
- // Center window in screen
- windRect = gWindowP->portRect;
- CenterRect(&windRect, &qd.screenBits.bounds);
-
- // Make sure window is aligned to long-word boundaries (for 8-bit mode)
- windRect.left = windRect.left>>2<<2;
-
- MoveWindow(gWindowP, windRect.left, windRect.top, false);
-
- ShowWindow(gWindowP);
- SetPort(gWindowP);
- mBarUpdateRgn = SWHideMenuBar(gWindowP); // Must be done *after* showing window!
- EraseRgn(mBarUpdateRgn);
-
- if (kInterlacedMode)
- PaintRect(&gWindowP->portRect); // Blacken window for Interlaced mode
- }
- else
- CantFindResource();
-
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
-
- worldRect = gWindowP->portRect;
- InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
-
- // Since our circular world must be evenly divisible by our offscreen area...
- SetRect(&offscreenRect, 0, 0, 640, 480);
-
- // Create the scrolling sprite world
- err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP,
- &worldRect, &offscreenRect, 0);
- FatalError(err);
-
- // Create the sprite layers
- err = SWCreateSpriteLayer(&gBallSpriteLayerP);
- FatalError(err);
- err = SWCreateSpriteLayer(&gBottomSpriteLayerP);
- FatalError(err);
- err = SWCreateSpriteLayer(&gTopSpriteLayerP);
- FatalError(err);
- err = SWCreateSpriteLayer(&gMeterSpriteLayerP);
- FatalError(err);
-
- // Add them to the world
- SWAddSpriteLayer(gSpriteWorldP, gBallSpriteLayerP); // Bottom
- SWAddSpriteLayer(gSpriteWorldP, gBottomSpriteLayerP); // Middle
- SWAddSpriteLayer(gSpriteWorldP, gTopSpriteLayerP); // Middle
- SWAddSpriteLayer(gSpriteWorldP, gMeterSpriteLayerP); // Top
-
- SWSetSpriteLayerUnderTileLayer(gBallSpriteLayerP, 0);
- SWSetSpriteLayerUnderTileLayer(gBottomSpriteLayerP, 0);
-
- // Determine what DrawProcs to use
- if (gSpriteWorldP->pixelDepth == 8) // 256 colors
- {
- if (kInterlacedMode)
- {
- gSpriteDrawProc = BP8BitInterlacedMaskDrawProc;
- gScreenDrawProc = BP8BitInterlacedRectDrawProc;
- gDoubleRectDrawProc = BP8BitInterlacedDoubleRectDrawProc;
- SWSetPartialMaskDrawProc(gSpriteWorldP, BP8BitInterlacedPartialMaskDrawProc);
- }
- else
- {
- gSpriteDrawProc = BlitPixie8BitMaskDrawProc;
- gScreenDrawProc = SWStdWorldDrawProc;
- gDoubleRectDrawProc = BlitPixie8BitDoubleRectDrawProc;
- SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
- }
- }
- else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- if (kInterlacedMode && gSpriteWorldP->pixelDepth > 2)
- {
- gSpriteDrawProc = BPAllBitInterlacedMaskDrawProc;
- gScreenDrawProc = BPAllBitInterlacedRectDrawProc;
- SWSetPartialMaskDrawProc(gSpriteWorldP, BPAllBitInterlacedPartialMaskDrawProc);
- if (gSpriteWorldP->pixelDepth == 16)
- gDoubleRectDrawProc = BP16BitInterlacedDoubleRectDrawProc;
- }
- else
- {
- gSpriteDrawProc = BlitPixieAllBitMaskDrawProc;
- gScreenDrawProc = BlitPixieAllBitRectDrawProc;
- SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
- if (gSpriteWorldP->pixelDepth == 16)
- gDoubleRectDrawProc = BlitPixie16BitDoubleRectDrawProc;
- }
- }
- else
- {
- gSpriteDrawProc = SWStdSpriteDrawProc;
- gScreenDrawProc = SWStdWorldDrawProc;
- gDoubleRectDrawProc = NULL;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpTiling
- ///--------------------------------------------------------------------------------------
-
- void SetUpTiling( void )
- {
- short resIDOffset;
- short row, col;
- OSErr err;
-
- err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
- FatalError(err);
-
- err = SWCreateTileMap(&gTileMapStructP, kTileMapRows, kTileMapCols);
- FatalError(err);
-
- SWInstallTileMap(gSpriteWorldP, gTileMapStructP, 0);
- gTileMap = gTileMapStructP->tileMap;
-
- // Determine whether to load B&W or color graphics
- if (gSpriteWorldP->pixelDepth <= 2)
- resIDOffset = kBWPictResIDOffset;
- else
- resIDOffset = 0;
-
- // Load first set of tiles
- err = SWLoadTilesFromPictResource(
- gSpriteWorldP,
- kWallTile, // startTileID
- kLastDiamondTile, // endTileID
- 200 + resIDOffset, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 1, // horizBorderWidth
- 1); // vertBorderHeight
- FatalError(err);
-
- // Load masked set of tiles
- err = SWLoadTilesFromPictResource(
- gSpriteWorldP,
- kTunnelTile1, // startTileID
- kWireTile2, // endTileID
- 201 + resIDOffset, // pictResID
- 401, // maskResID
- kFatMask, // maskType
- 1, // horizBorderWidth
- 1); // vertBorderHeight
- FatalError(err);
-
-
- // Set up tileMap
- for (row = 0; row < kTileMapRows; row++)
- {
- for (col = 0; col < kTileMapCols; col++)
- {
- if (row == 0 || col == 0 || row == kTileMapRows-1 || col == kTileMapCols-1)
- gTileMap[row][col] = kWallTile;
- else if (row > kTileMapRows / 2)
- gTileMap[row][col] = kWireTile1;
- else if ((row/kDiamondSpace)*kDiamondSpace == row &&
- (col/kDiamondSpace)*kDiamondSpace == col)
- {
- gTileMap[row][col] = kDiamondTile;
- gNumDiamondsInMap++;
- }
- else
- gTileMap[row][col] = kGrassTile;
- }
- }
-
-
- // Add tunnel to tileMap
- row = kTileMapRows / 2;
-
- for (col = 1; col < kTileMapCols-1; col += 2)
- {
- gTileMap[row][col] = kTunnelTile1;
- gTileMap[row][col+1] = kTunnelTile2;
- gTileMap[row+1][col] = kTunnelTile4;
- gTileMap[row+1][col+1] = kTunnelTile5;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateMainBallSprite
- ///--------------------------------------------------------------------------------------
-
- void CreateMainBallSprite( void )
- {
- OSErr err;
-
- // Create the ball sprite
- err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gSimpleSpriteP, NULL,
- 128, 1, kFatMask);
- FatalError(err);
-
- // Set up the ball sprite
- SWAddSprite(gBallSpriteLayerP, gSimpleSpriteP);
- SWSetSpriteMoveProc(gSimpleSpriteP, KeySpriteMoveProc);
- SWSetSpriteLocation(gSimpleSpriteP, kStartCol * kTileWidth, kStartRow * kTileHeight);
- SWSetSpriteMoveDelta(gSimpleSpriteP, 0, 0);
- SWSetSpriteDrawProc(gSimpleSpriteP, gSpriteDrawProc);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateDiamondMeterSprite
- ///--------------------------------------------------------------------------------------
-
- void CreateDiamondMeterSprite( void )
- {
- short spriteResID;
- OSErr err;
-
- // Calculate resource ID for diamond meter sprite
- if (gSpriteWorldP->pixelDepth <= 2)
- spriteResID = 302;
- else
- spriteResID = 202;
-
- // Create the diamond meter sprite
- err = SWCreateSpriteFromPictResource(gSpriteWorldP,
- &gDiamondMeterSpriteP,
- NULL, // pointer to memory for sprite
- spriteResID, // picture resource id
- 402, // mask resource id
- 1, // max frames
- kPixelMask); // mask type
- FatalError(err);
-
- SWAddSprite(gMeterSpriteLayerP, gDiamondMeterSpriteP);
- SWSetSpriteDrawProc(gDiamondMeterSpriteP, gSpriteDrawProc);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateBallSprites
- ///--------------------------------------------------------------------------------------
-
- void CreateBallSprites( void )
- {
- SpritePtr simpleSpriteP;
- short spriteNum;
- Rect moveBoundsRect;
- OSErr err;
-
- // Create the first sprite
- err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gSpriteArray[0], NULL,
- 200, 2, kFatMask);
- FatalError(err);
-
- // Save the sprite's width. This info used when scaling later.
- gScaledWidth = gSpriteArray[0]->destFrameRect.right - gSpriteArray[0]->destFrameRect.left;
- gScaledHeight = gSpriteArray[0]->destFrameRect.bottom - gSpriteArray[0]->destFrameRect.top;
- gOriginalWidth = gScaledWidth;
- gOriginalHeight = gScaledHeight;
-
- // clone the rest of the sprites off the first one
- for (spriteNum = 1; spriteNum < kNumSprites; spriteNum++)
- {
- err = SWCloneSprite(gSpriteArray[0], &gSpriteArray[spriteNum], NULL);
- FatalError(err);
- }
-
- // Calculate size of virtual world
- SetRect(&moveBoundsRect, 0, 0, kTileMapCols * kTileWidth, kTileMapRows * kTileHeight);
-
-
- // Set up the sprites in random locations with random deltas
- for (spriteNum = 0; spriteNum < kNumSprites; spriteNum++)
- {
- simpleSpriteP = gSpriteArray[spriteNum];
-
- if (GetRandom(0,1) == 0)
- SWAddSprite(gBottomSpriteLayerP, gSpriteArray[spriteNum]); // Add above wire tiles
- else
- SWAddSprite(gTopSpriteLayerP, gSpriteArray[spriteNum]); // Add below wire tiles
-
- SWSetSpriteMoveProc(simpleSpriteP, BallSpriteMoveProc);
- SWSetSpriteDrawProc(simpleSpriteP, gSpriteDrawProc);
- SWSetSpriteCollideProc(simpleSpriteP, BallSpriteCollideProc);
-
- SWSetSpriteLocation(simpleSpriteP,
- GetRandom(0, moveBoundsRect.right),
- GetRandom(0, moveBoundsRect.bottom) );
-
- do
- {
- SWSetSpriteMoveDelta(simpleSpriteP,
- GetRandom(-kMaxSpriteMoveDelta, kMaxSpriteMoveDelta),
- GetRandom(-kMaxSpriteMoveDelta, kMaxSpriteMoveDelta));
- } while (simpleSpriteP->horizMoveDelta == 0 || simpleSpriteP->vertMoveDelta == 0);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpAnimation
- ///--------------------------------------------------------------------------------------
-
- void SetUpAnimation( void )
- {
- Rect moveBoundsRect;
-
- SWLockSpriteWorld(gSpriteWorldP);
-
- // Set up data used by the SmoothScrollingWorldMoveProc
- gScreenMidRect = gSimpleSpriteP->curFrameP->frameRect;
- CenterRect( &gScreenMidRect, &gSpriteWorldP->backRect );
-
- SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
- SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
- SWSetCleanUpSpriteWorld(gSpriteWorldP);
-
- // movement boundary = size of tileMap
- SetRect(&moveBoundsRect, 0,0, kTileMapCols * kTileWidth, kTileMapRows * kTileHeight);
-
- SWSetScrollingWorldMoveBounds(gSpriteWorldP, &moveBoundsRect);
- SWSetScrollingWorldMoveProc(gSpriteWorldP, KeyScrollRectMoveProc, NULL);
-
- SWSetTileChangeProc(gSpriteWorldP, TileChangeProc);
-
- // Set starting position of diamond meter sprite
- DiamondMeterSpriteMoveProc(gDiamondMeterSpriteP);
-
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, gScreenDrawProc);
- SWSetDoubleRectDrawProc(gSpriteWorldP, gDoubleRectDrawProc);
-
- // Make sure CopyBits, if used, doesn't try to colorize things
- SWSetPortToWindow(gSpriteWorldP);
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- SWDrawTilesInCircularBackground(gSpriteWorldP);
- SWUpdateCircularSpriteWorld(gSpriteWorldP);
-
- if (kDoZoomOutIntro)
- DoZoomOut();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // DoZoomOut - a special effect
- ///--------------------------------------------------------------------------------------
-
- void DoZoomOut( void )
- {
- Rect srcRect = gSpriteWorldP->backRect;
- Rect myBackRect;
- DrawProcPtr drawProcP;
- short newWidth, newHeight, worldWidth, worldHeight;
- double percent, increase;
-
- // Determine what DrawProc to use
- if (gSpriteWorldP->pixelDepth == 8)
- drawProcP = BlitPixie8BitScaledRectDrawProc;
- else if (gSpriteWorldP->pixelDepth == 16)
- drawProcP = BlitPixie16BitScaledRectDrawProc;
- else
- drawProcP = SWStdWorldDrawProc;
-
- worldWidth = SW_RECT_WIDTH(gSpriteWorldP->windRect);
- worldHeight = SW_RECT_HEIGHT(gSpriteWorldP->windRect);
- myBackRect = gSpriteWorldP->windRect;
- OffsetRect(&myBackRect, -myBackRect.left, -myBackRect.top);
-
- increase = 1;
- for (percent = 2; percent <= 100 && !Button(); percent += increase)
- {
- increase += .1; // This makes the scaling go faster the closer we get to the end
-
- // Look in SWCommonHeaders.h to see what these macros do
- newWidth = ((double)worldWidth * percent) / 100;
- newHeight = ((double)worldHeight * percent) / 100;
-
- SW_SET_RECT(srcRect, 0, 0, newWidth, newHeight);
- CenterRect(&srcRect, &myBackRect);
-
- (*drawProcP)(gSpriteWorldP->workFrameP, gSpriteWorldP->windowFrameP,
- &srcRect, &gSpriteWorldP->windRect);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RunAnimation
- ///--------------------------------------------------------------------------------------
-
- void RunAnimation( void )
- {
- unsigned long frames;
-
- frames = 0;
- StartTimer();
-
- FatalError( SWStickyError() ); // Make sure no errors got past us during setup
-
- while (!Button())
- {
- SWProcessCircularSpriteWorld(gSpriteWorldP);
-
- // We call this in case the Control Strip or something changes our window's visRgn
- KeepMenuBarHidden(gWindowP);
-
- // Move diamond meter sprite to new visScrollRect location
- DiamondMeterSpriteMoveProc(gDiamondMeterSpriteP);
-
- // Check for collisions with the ball sprites
- SWCollideCircularSpriteLayer(gSpriteWorldP, gTopSpriteLayerP, gTopSpriteLayerP);
- SWCollideCircularSpriteLayer(gSpriteWorldP, gBottomSpriteLayerP, gBottomSpriteLayerP);
- SWCollideCircularSpriteLayer(gSpriteWorldP, gBottomSpriteLayerP, gTopSpriteLayerP);
-
- // Make sure no errors occurred during a MoveProc, etc.
- FatalError( SWStickyError() );
-
- SWAnimateCircularSpriteWorld(gSpriteWorldP);
-
- if (gSpriteWorldP->frameHasOccurred)
- frames++;
- }
-
-
- ShowResults(frames);
- SWShowMenuBar(gWindowP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShutDown (clean up and dispose of the SpriteWorld)
- ///--------------------------------------------------------------------------------------
-
- void ShutDown( void )
- {
- SWDisposeSpriteWorld(&gSpriteWorldP);
- SWExitSpriteWorld();
-
- FlushEvents(everyEvent, 0);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // TileChangeProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void TileChangeProc(
- SpriteWorldPtr spriteWorldP)
- {
- short curImage;
- static short wallDelay = 0, diamondDelay = 0;
- static short oldTicks = 0;
- short ticksPassed, ticks;
-
- // Initialize oldTicks the first time this function is called
- if (oldTicks == 0)
- oldTicks = TickCount();
-
- ticks = TickCount();
- ticksPassed = ticks - oldTicks; // Number of ticks passed since last call
- oldTicks = ticks;
-
- // kWallTile
- wallDelay += ticksPassed;
- if (wallDelay >= kWallFrameRate)
- {
- curImage = spriteWorldP->curTileImage[kWallTile];
- if (curImage < kLastWallTile)
- curImage++;
- else
- curImage = kWallTile;
-
- SWChangeCircularTileImage(spriteWorldP, kWallTile, curImage);
- wallDelay = 0;
- }
-
-
- // kDiamondTile
- diamondDelay += ticksPassed;
- if (diamondDelay >= kDiamondFrameRate)
- {
- curImage = spriteWorldP->curTileImage[kDiamondTile];
- if (curImage < kLastDiamondTile)
- curImage++;
- else
- curImage = kDiamondTile;
-
- SWChangeCircularTileImage(spriteWorldP, kDiamondTile, curImage);
- diamondDelay = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // KeySpriteMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void KeySpriteMoveProc(SpritePtr srcSpriteP)
- {
- short row, col;
- short rowDelta, colDelta;
- short tile;
-
- UpdateKeys(); // Put the latest key values in the keys structure
-
-
- row = srcSpriteP->destFrameRect.top / kTileHeight;
- col = srcSpriteP->destFrameRect.left / kTileWidth;
-
- if (row * kTileHeight == srcSpriteP->destFrameRect.top &&
- col * kTileWidth == srcSpriteP->destFrameRect.left)
- {
- tile = gTileMap[row][col];
-
- // Leave black trail behind sprite
- if (tile == kGrassTile || tile == kDiamondTile)
- SWDrawCircularTile(gSpriteWorldP, 0, row, col, kBlackTile);
- else if (tile == kTunnelTile2 || tile == kTunnelTile5 || tile == kWireTile1)
- SWDrawCircularTile(gSpriteWorldP, 0, row, col, tile+1);
-
- if (tile == kDiamondTile)
- {
- gNumDiamonds++; // Increase number of diamonds sprite has collected
- UpdateDiamondMeter(); // Update meter
- }
-
-
- rowDelta = 0;
- colDelta = 0;
-
- if (gBallKeys.left)
- colDelta = -1;
- else if (gBallKeys.right)
- colDelta = 1;
- else if (gBallKeys.up)
- rowDelta = -1;
- else if (gBallKeys.down)
- rowDelta = 1;
-
-
-
- tile = gTileMap[row + rowDelta][col + colDelta];
-
- if (tile != kWallTile && tile != kTunnelTile1 && tile != kTunnelTile4)
- {
- srcSpriteP->vertMoveDelta = rowDelta * kSpriteMoveDelta;
- srcSpriteP->horizMoveDelta = colDelta * kSpriteMoveDelta;
- }
- else
- {
- srcSpriteP->vertMoveDelta = 0;
- srcSpriteP->horizMoveDelta = 0;
- }
- }
-
- SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, srcSpriteP->vertMoveDelta);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // DiamondMeterSpriteMoveProc - not installed as a MoveProc, but called directly
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void DiamondMeterSpriteMoveProc(SpritePtr srcSpriteP)
- {
- // Move sprite to top-left corner of current visScrollRect location
- SWMoveSprite(srcSpriteP,
- gSpriteWorldP->visScrollRect.left + 10,
- gSpriteWorldP->visScrollRect.top + 10);
- }
-
- ///--------------------------------------------------------------------------------------
- // BallSpriteMoveProc - used to move all the randomly moving balls
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BallSpriteMoveProc(SpritePtr srcSpriteP)
- {
- SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, srcSpriteP->vertMoveDelta);
-
- // Reset sprite back to normal frame (in case it had a collision and was changed)
- if (srcSpriteP->curFrameIndex != 0)
- SWSetCurrentFrameIndex(srcSpriteP, 0);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BallSpriteCollideProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BallSpriteCollideProc(SpritePtr srcSpriteP, SpritePtr dstSpriteP, Rect *sectRect)
- {
- #pragma unused(sectRect) // Tell CodeWarrior this variable is unused
-
- // Turn the sprites whiter while they are colliding
- if (srcSpriteP->curFrameIndex != 1)
- SWSetCurrentFrameIndex(srcSpriteP, 1);
-
- if (dstSpriteP->curFrameIndex != 1)
- SWSetCurrentFrameIndex(dstSpriteP, 1);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateDiamondMeter - change the meter Sprite's image and mask
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void UpdateDiamondMeter( void )
- {
- double percent;
- Rect meterRect;
-
- percent = (double)gNumDiamonds / gNumDiamondsInMap;
-
- // 108 = length of meter; 17 = offset from start of meter
- SetRect(&meterRect, 17, 2, (108 * percent) + 17, 14);
-
-
- // Set port to our sprite's framePort GWorld
- SetGWorld(gDiamondMeterSpriteP->curFrameP->framePort, nil);
-
- ForeColor(magentaColor);
- PaintRect(&meterRect);
-
- // IMPORTANT: Set the color back when done! (In case CopyBits is used later)
- ForeColor(blackColor);
-
-
- // Set port to our sprite's pixel mask GWorld
- SetGWorld(gDiamondMeterSpriteP->curFrameP->maskPort, nil);
-
- // Mask image is inverted when in 8-bit or less
- if (gSpriteWorldP->pixelDepth <= 8)
- ForeColor(whiteColor);
- else
- ForeColor(blackColor);
-
- PaintRect(&meterRect);
- ForeColor(blackColor);
-
-
- // Set sprite to be redrawn, since we've changed its image
- gDiamondMeterSpriteP->needsToBeDrawn = true;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // KeyScrollRectMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void KeyScrollRectMoveProc(
- SpriteWorldPtr spriteWorldP,
- SpritePtr followSpriteP)
- {
- #pragma unused(followSpriteP) // Tell CodeWarrior this variable is unused
-
- UpdateKeys();
-
- spriteWorldP->vertScrollDelta = (gScrollKeys.down - gScrollKeys.up) * kScrollSpeed;
- spriteWorldP->horizScrollDelta = (gScrollKeys.right - gScrollKeys.left) * kScrollSpeed;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateKeys (Put the latest key values in the keys structure)
- ///--------------------------------------------------------------------------------------
-
- void UpdateKeys( void )
- {
- EventRecord event;
- short theKey;
- Boolean isDown;
-
- while ( GetOSEvent( (keyUpMask | keyDownMask), &event ) )
- {
- theKey = (event.message & keyCodeMask) >> 8;
- isDown = (event.what != keyUp);
-
- if (theKey == kLeftArrowKey)
- gBallKeys.left = isDown;
- else if (theKey == kRightArrowKey)
- gBallKeys.right = isDown;
- else if (theKey == kDownArrowKey)
- gBallKeys.down = isDown;
- else if (theKey == kUpArrowKey)
- gBallKeys.up = isDown;
-
- if (theKey == kLeftKeyPad)
- gScrollKeys.left = isDown;
- else if (theKey == kRightKeyPad)
- gScrollKeys.right = isDown;
- else if (theKey == kDownKeyPad)
- gScrollKeys.down = isDown;
- else if (theKey == kUpKeyPad)
- gScrollKeys.up = isDown;
-
- if (theKey == kMinusKey)
- gMinusKeyIsDown = isDown;
- else if (theKey == kPlusKey)
- gPlusKeyIsDown = isDown;
- else if (theKey == kReturnKey)
- gReturnKeyIsDown = isDown;
- }
-
- UpdateScaledSprites();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateScaledSprites
- ///--------------------------------------------------------------------------------------
-
- void UpdateScaledSprites( void )
- {
- short offset;
-
- if (gMinusKeyIsDown)
- {
- if (gScaledWidth > 5 && gScaledHeight > 5)
- {
- gScaledWidth -= 2;
- gScaledHeight -= 2;
- ScaleSprites(1);
- }
- }
-
- if (gPlusKeyIsDown)
- {
- gScaledWidth += 2;
- gScaledHeight += 2;
- ScaleSprites(-1);
- }
-
- if (gReturnKeyIsDown)
- {
- offset = gScaledWidth - gOriginalWidth;
- gScaledWidth = gOriginalWidth;
- gScaledHeight = gOriginalHeight;
- ScaleSprites( offset / 2 );
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ScaleSprites
- ///--------------------------------------------------------------------------------------
-
- void ScaleSprites( short spriteOffset )
- {
- SpritePtr curSpriteP;
-
- if (gSpriteWorldP->pixelDepth < 8 || gSpriteWorldP->pixelDepth > 16)
- return;
-
- // Update all sprites in gTopSpriteLayer
- curSpriteP = SWGetNextSprite(gTopSpriteLayerP, NULL);
- while (curSpriteP != NULL)
- {
- SWSetSpriteScaledSize(curSpriteP, gScaledWidth, gScaledHeight);
- SWOffsetSprite(curSpriteP, spriteOffset, spriteOffset);
- curSpriteP = SWGetNextSprite(gTopSpriteLayerP, curSpriteP);
- }
-
- // Update all sprites in gBottomSpriteLayer
- curSpriteP = SWGetNextSprite(gBottomSpriteLayerP, NULL);
- while (curSpriteP != NULL)
- {
- SWSetSpriteScaledSize(curSpriteP, gScaledWidth, gScaledHeight);
- SWOffsetSprite(curSpriteP, spriteOffset, spriteOffset);
- curSpriteP = SWGetNextSprite(gBottomSpriteLayerP, curSpriteP);
- }
- }